package ginplus

import (
	"errors"
)

type Filter interface {
	DoFilter(mapping *HandlerMappingWrapper, chain FilterChain)
}

type FilterChain interface {
	DoFilter(mapping *HandlerMappingWrapper)
}

func NewDefaultFilterChain(lastLogic FilterChain) *DefaultFilterChain {
	if lastLogic == nil {
		panic(errors.New("last logic cannot be nil"))
	}
	return &DefaultFilterChain{
		lastLogic: lastLogic,
	}
}

var _ FilterChain = (*DefaultFilterChain)(nil)

type DefaultFilterChain struct {
	lastLogic FilterChain
	filters   []Filter
	position  int
}

func (my *DefaultFilterChain) DoFilter(mapping *HandlerMappingWrapper) {
	filterNum := len(my.filters)
	if my.position == filterNum {
		my.lastLogic.DoFilter(mapping)
	} else {
		my.position++
		filter := my.filters[my.position-1]
		filter.DoFilter(mapping, my)
	}
}

func (my *DefaultFilterChain) AddFilter(filters ...Filter) {
	my.filters = append(my.filters, filters...)
}
